using System.Collections.Generic;
using System.Collections.ObjectModel;
using OracleInternal.Common;
using OracleInternal.SqlAndPlsqlParser.LocalParsing.Ansi;
using OracleInternal.SqlAndPlsqlParser.RuleProcessors;

namespace OracleInternal.SqlAndPlsqlParser.LocalParsing
{
	internal class OracleLpParserContext : OracleMbEarleyParserMultiContext
	{
		protected List<OracleLpStatement> m_vStatements;

		protected OracleLpTextFragment m_vCurrentStatementText;

		private int m_vCurrentStatementBindVarCount;

		private Dictionary<ParseNode, OracleLpBindParameter> m_vCurrentStatementBindVarParseNodes = new Dictionary<ParseNode, OracleLpBindParameter>();

		private OracleLpStatementClauseType m_vCurrentStatementClause;

		protected OracleLpStatement m_vCurrentStatement;

		protected bool m_vHandleBindVariables;

		protected IOracleMetadata m_vActiveODPContext;

		protected OracleLpSubquery m_vActiveLpSubquery;

		protected OracleLpStatementDataContainer m_vActiveLpTableReference;

		protected OracleLpTablePrimary m_vActiveLpTablePrimary;

		protected OracleLpQteNamedObject m_vActiveLpQTENamedObject;

		protected OracleLpCondition m_vActiveLpCondition;

		protected OracleLpColumn m_vActiveLpColumn;

		protected OracleLpExpression m_vActiveLpExpression;

		protected OracleLpColumnMappedQueryName m_vActiveColumnMappedQueryName;

		protected OracleLpBaseAnsiJoinClause m_vActiveAnsiJoinClause;

		public ReadOnlyCollection<OracleLpStatement> Statements
		{
			get
			{
				if (m_vStatements != null)
				{
					return m_vStatements.AsReadOnly();
				}
				return null;
			}
		}

		public OracleLpTextFragment CurrentStatementText
		{
			get
			{
				return m_vCurrentStatementText;
			}
			set
			{
				m_vCurrentStatementText = value;
			}
		}

		public int CurrentStatementBindVarCount
		{
			get
			{
				return m_vCurrentStatementBindVarCount;
			}
			set
			{
				m_vCurrentStatementBindVarCount = value;
			}
		}

		public Dictionary<ParseNode, OracleLpBindParameter> CurrentStatementBindVarParseNodes => m_vCurrentStatementBindVarParseNodes;

		public OracleLpStatementClauseType CurrentStatementClause
		{
			get
			{
				return m_vCurrentStatementClause;
			}
			set
			{
				m_vCurrentStatementClause = value;
			}
		}

		public OracleLpStatement CurrentStatement
		{
			get
			{
				return m_vCurrentStatement;
			}
			set
			{
				if (m_vCurrentStatement == value)
				{
					return;
				}
				m_vCurrentStatement = value;
				if (value != null)
				{
					if (m_vStatements == null)
					{
						m_vStatements = new List<OracleLpStatement>();
					}
					m_vStatements.Add(value);
					m_vCurrentStatementBindVarCount = 0;
					m_vCurrentStatementBindVarParseNodes.Clear();
				}
			}
		}

		public bool HandleBindVariables
		{
			get
			{
				return m_vHandleBindVariables;
			}
			set
			{
				m_vHandleBindVariables = value;
			}
		}

		static OracleLpParserContext()
		{
			OracleMbEarleyRuleMultiProcessor.Postprocess += ProcessBindVariables;
		}

		public OracleLpParserContext(Earley parser, OracleMbRuleProcessorTableDictionary<OracleMbEarleyRuleMultiProcessorTable> ruleProcessorTableDictionary)
			: base(parser, ruleProcessorTableDictionary)
		{
		}

		public override object GetActiveObject(int type)
		{
			switch (type)
			{
			case 3:
				return m_vCurrentStatement;
			case 4:
				return m_vActiveLpSubquery;
			case 5:
				if (m_vActiveLpSubquery.SubqueryType != 0)
				{
					return null;
				}
				return ((OracleLpQueryBlockSubquery)m_vActiveLpSubquery).QueryBlock;
			case 7:
				return m_vActiveLpTableReference;
			case 8:
				return m_vActiveLpTablePrimary;
			case 6:
			{
				if (m_vActiveLpSubquery.SubqueryType != 0)
				{
					return null;
				}
				List<OracleLpStatementDataContainer> terms = ((OracleLpQueryBlockSubquery)m_vActiveLpSubquery).QueryBlock.FromClause.Terms;
				return terms[terms.Count - 1];
			}
			case 9:
				return m_vActiveLpCondition;
			case 10:
				return m_vActiveLpColumn;
			case 11:
				return m_vActiveLpExpression;
			case 0:
				return m_vActiveODPContext;
			case 12:
				return m_vActiveColumnMappedQueryName;
			case 13:
				return m_vActiveLpQTENamedObject;
			case 14:
				return m_vActiveAnsiJoinClause;
			default:
				return null;
			}
		}

		public override void SetActiveObject(int type, object ao)
		{
			switch (type)
			{
			case 3:
				m_vCurrentStatement = (OracleLpStatement)ao;
				break;
			case 4:
				m_vActiveLpSubquery = (OracleLpSubquery)ao;
				break;
			case 7:
				m_vActiveLpTableReference = (OracleLpStatementDataContainer)ao;
				break;
			case 8:
				m_vActiveLpTablePrimary = (OracleLpTablePrimary)ao;
				break;
			case 9:
				m_vActiveLpCondition = (OracleLpCondition)ao;
				break;
			case 10:
				m_vActiveLpColumn = (OracleLpColumn)ao;
				break;
			case 11:
				m_vActiveLpExpression = (OracleLpExpression)ao;
				break;
			case 0:
				m_vActiveODPContext = (IOracleMetadata)ao;
				break;
			case 12:
				m_vActiveColumnMappedQueryName = (OracleLpColumnMappedQueryName)ao;
				break;
			case 13:
				m_vActiveLpQTENamedObject = (OracleLpQteNamedObject)ao;
				break;
			case 14:
				m_vActiveAnsiJoinClause = (OracleLpBaseAnsiJoinClause)ao;
				break;
			case 1:
			case 2:
			case 5:
			case 6:
				break;
			}
		}

		public override void Clear()
		{
			base.Clear();
			m_vRuleProcessorTable = GetRuleProcessorTable("ODPCommands");
			m_vCurrentStatementText = null;
			m_vStatements = null;
			m_vCurrentStatement = null;
			m_vCurrentStatementBindVarCount = 0;
			m_vCurrentStatementBindVarParseNodes.Clear();
			m_vCurrentStatementClause = OracleLpStatementClauseType.Unknown;
			m_vHandleBindVariables = false;
		}

		public static void ProcessBindVariables(ParseNode pn, OracleMbEarleyParserMultiContext ctx)
		{
			OracleLpParserContext oracleLpParserContext = (OracleLpParserContext)ctx;
			if (oracleLpParserContext.m_vHandleBindVariables)
			{
				oracleLpParserContext.m_vHandleBindVariables = false;
				OracleMbEarleyRuleMultiProcessorTable ruleProcessorTable = ctx.RuleProcessorTable;
				ctx.RuleProcessorTable = ctx.GetRuleProcessorTable("bind_var");
				OracleMbEarleyRuleMultiProcessor.TraverseAndProcessNodeSubtreeRules(pn, ctx, ctx.RuleProcessorTable.RuleProcessors);
				ctx.RuleProcessorTable = ruleProcessorTable;
			}
		}
	}
}
